package com.poizon.infrastructure.common.util;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Supplier;

/**
 * 工具类/异常重试
 */
@Slf4j
public class RetryUtil {
    /**
     * 重试执行给定的任务
     *
     * @param task          要执行的任务
     * @param maxRetries    最大重试次数
     * @param <T>           返回类型
     * @param stopException 如果是该异常类型则提前停止重试
     * @return 任务的返回结果
     * @throws Exception 如果达到最大重试次数后仍然失败，则抛出异常
     */
    @SneakyThrows
    public static <T> T retry(Supplier<T> task, int maxRetries, Class<? extends Exception> stopException) {
        int retries = 1;
        Exception exception = null;
        while (retries <= maxRetries) {
            try {
                return task.get();
            } catch (Exception e) {
                exception = e;
                if (stopException != null && e.getClass().equals(stopException)) {
                        log.debug(">异常类型为:{},提前终止重试", stopException);
                    throw e;
                }

                    log.debug(">开始第{}次重试", retries);

                retries++;
            }
        }
        log.warn(">到达最大重试次数,error:{}", exception.getMessage());
        throw exception;
    }

    public static <T> T retry(Supplier<T> task, int maxRetries) {
        return retry(task, maxRetries, null);
    }
}
